package edu.stanford.bmir.protege.web.server.stkosutil.enricher.handlers;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import org.semanticweb.owlapi.model.EntityType;
import org.semanticweb.owlapi.model.OWLAnnotation;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.util.OWLEntityRemover;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;

import edu.stanford.bmir.protege.web.client.rpc.stkosutil.common.UtilConstants;
import edu.stanford.bmir.protege.web.client.rpc.stkosutil.enricher.CancelEnricherResult;
import edu.stanford.bmir.protege.web.client.rpc.stkosutil.enricher.actions.CancelEnricherAction;
import edu.stanford.bmir.protege.web.server.owlapi.AssertedClassHierarchyProvider;
import edu.stanford.bmir.protege.web.server.owlapi.OWLAPIProject;
import edu.stanford.bmir.protege.web.server.owlapi.OWLAPIProjectManager;
import edu.stanford.bmir.protege.web.server.owlapi.RenderingManager;
import edu.stanford.bmir.protege.web.server.stkosutil.enricher.CandidateClassHolder;
import edu.stanford.bmir.protege.web.shared.project.ProjectId;
import edu.stanford.bmir.protege.web.shared.user.UserId;

public class CancelEnricherActionHandler {

	public CancelEnricherResult execute(String projectName,
			CancelEnricherAction action, UserId userId) {
		CancelEnricherResult result = new CancelEnricherResult();
		if (!checkNull(projectName) && !checkNull(action) && !checkNull(userId)) {
			OWLAPIProject project = this.getProject(projectName);

			if (!checkNull(project)) {
				OWLEntityRemover remover1 = new OWLEntityRemover(project
						.getRootOntology().getOWLOntologyManager(), project
						.getRootOntology().getImportsClosure());

				OWLOntology ontology = project.getRootOntology();

				Set<OWLClass> s1Classes = ontology.getClassesInSignature();
				for (OWLClass owlClass : s1Classes) {
					if (hasEnricherflag(project, owlClass)) {
						result.setDelClass((result.getDelClass() + 1));
						owlClass.accept(remover1);
					}
				}

				Set<OWLAnnotationProperty> s1AnnPropertyes = ontology
						.getAnnotationPropertiesInSignature();
				for (OWLAnnotationProperty owlProperty : s1AnnPropertyes) {
					if (hasEnricherflag(project, owlProperty)) {
						result.setDelProperty((result.getDelProperty() + 1));
						owlProperty.accept(remover1);
					}
				}
				Set<OWLDataProperty> s1DataPropertyes = ontology
						.getDataPropertiesInSignature();
				for (OWLDataProperty owlProperty : s1DataPropertyes) {
					if (hasEnricherflag(project, owlProperty)) {
						result.setDelProperty((result.getDelProperty() + 1));
						owlProperty.accept(remover1);
					}
				}
				Set<OWLObjectProperty> s1ObjPropertyes = ontology
						.getObjectPropertiesInSignature();
				for (OWLObjectProperty owlProperty : s1ObjPropertyes) {
					if (hasEnricherflag(project, owlProperty)) {
						result.setDelProperty((result.getDelProperty() + 1));
						owlProperty.accept(remover1);
					}
				}

				List<OWLOntologyChange> changeList = remover1.getChanges();
				project.applyChanges(userId, changeList, "删除project{"
						+ projectName + "}有丰富标记的Entity");
			}
		}
		return result;
	}

	final static OWLAPIProjectManager PM = OWLAPIProjectManager
			.getProjectManager();

	public OWLAPIProject getProject(String projectName) {
		OWLAPIProject op = null;
		if (!checkNull(projectName)) {
			op = PM.getProject(ProjectId.get(projectName));
		}
		return op;
	}

	public boolean checkNull(Object obj) {
		boolean f = false;
		if (obj == null) {
			f = true;
		}
		return f;
	}

	public boolean hasEnricherflag(OWLAPIProject project, OWLEntity ownEntity) {
		for (OWLAnnotation annotation : ownEntity.getAnnotations(project
				.getRootOntology(), project.getDataFactory().getRDFSComment())) {
			if (annotation.getValue() instanceof OWLLiteral) {
				OWLLiteral commentValue = (OWLLiteral) annotation.getValue();
				String value = commentValue.getLiteral();
				if (value.startsWith(UtilConstants.FLAG_ENRICHED)) {
					return true;
				}
			}
		}
		return false;
	}

	private List<CandidateClassHolder> loadAllClassList(OWLAPIProject project) {
		List<CandidateClassHolder> result = new ArrayList<CandidateClassHolder>();
		Stack<CandidateClassHolder> sClassHolders = new Stack<CandidateClassHolder>();
		CandidateClassHolder root = this.getRootClass(project);
		sClassHolders.push(root);
		while (!sClassHolders.empty()) {
			CandidateClassHolder currentClass = sClassHolders.pop();
			List<CandidateClassHolder> children = this.getSubclasses(project,
					currentClass.getName());
			Collections.reverse(children);
			for (CandidateClassHolder child : children) {
				sClassHolders.push(child);
			}
			result.add(currentClass);
		}
		return result;
	}

	private CandidateClassHolder getRootClass(OWLAPIProject project) {
		CandidateClassHolder holder = new CandidateClassHolder();
		RenderingManager rm = project.getRenderingManager();
		OWLClass owlThing = project.getDataFactory().getOWLThing();
		String browserText = rm.getBrowserText(owlThing);
		String name = owlThing.getIRI().toString();
		holder.setBrowserText(browserText);
		holder.setName(name);
		holder.setOwlClass(owlThing);
		return holder;
	}

	private List<CandidateClassHolder> getSubclasses(OWLAPIProject project,
			String className) {
		if (className == null) {
			return Collections.emptyList();
		}
		List<CandidateClassHolder> result = new ArrayList<CandidateClassHolder>();

		RenderingManager rm = project.getRenderingManager();
		AssertedClassHierarchyProvider hierarchyProvider = project
				.getClassHierarchyProvider();
		OWLClass cls = rm.getEntity(className, EntityType.CLASS);

		boolean checkForDeprecated = project.getRootOntology()
				.containsAnnotationPropertyInSignature(
						OWLRDFVocabulary.OWL_DEPRECATED.getIRI());
		for (OWLClass subclass : new ArrayList<OWLClass>(
				hierarchyProvider.getChildren(cls))) {
			boolean deprecated = false;
			String browserText = rm.getBrowserText(subclass);
			String name = subclass.getIRI().toString();
			CandidateClassHolder classHolder = new CandidateClassHolder();
			classHolder.setBrowserText(browserText);
			classHolder.setName(name);
			classHolder.setOwlClass(subclass);
			result.add(classHolder);
		}
		Collections.sort(result, new Comparator<CandidateClassHolder>() {
			public int compare(CandidateClassHolder o1, CandidateClassHolder o2) {
				String browserText1 = o1.getBrowserText();
				String browserText2 = o2.getBrowserText();
				if (browserText1.startsWith("'")) {
					browserText1 = browserText1.substring(1);
				}
				if (browserText2.startsWith("'")) {
					browserText2 = browserText2.substring(1);
				}
				return browserText1.compareToIgnoreCase(browserText2);
			}
		});
		return result;
	}
}
